VEH Hook 及 检测

您所在的位置:网站首页 硬件断点 hook VEH Hook 及 检测

VEH Hook 及 检测

2024-07-13 20:57| 来源: 网络整理| 查看: 265

SEH(Struct Exception Handler,结构化异常) VEH(Vector Exception Handler,向量异常处理) SEH是OS提供给线程来感知和处理异常的一种回调机制。 在Intel Win32平台上,由于FS寄存器问题指向当前的TIB(线程信息块),因此FS:[0]处能找到最新的一个EXCEPTION_REGISTRATION_RECORD结构。 typedef struct _EXCEPTION_REGISTRATION_RECORD {     struct _EXCEPTION_REGISTRATION_RECORD *Next;     PEXCEPTION_ROUTINE Handler; } EXCEPTION_REGISTRATION_RECORD; EXCEPTION_ROUTINE (     _Inout_ struct _EXCEPTION_RECORD *ExceptionRecord,     _In_ PVOID EstablisherFrame,     _Inout_ struct _CONTEXT *ContextRecord,     _In_ PVOID DispatcherContext     );

typedef EXCEPTION_ROUTINE *PEXCEPTION_ROUTINE; typedef struct _EXCEPTION_RECORD {     DWORD    ExceptionCode;     DWORD ExceptionFlags;     struct _EXCEPTION_RECORD *ExceptionRecord;     PVOID ExceptionAddress;     DWORD NumberParameters;     ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];     } EXCEPTION_RECORD;     XP之后,在基于线程的SEH基础增加了基于进程的VEH 比较: 1.SEH基于线程,VEH基于进程 2.优先级:调试器 > VEH > SEH 即KiUserExceptionDispatcher()函数先检查进程是否处理调试,然后VEH,最后SEH. 3.SEH单链表,VEH双链表,VEH节点可挂在头上或尾上。 注册VEH的回调API: PVOID WINAPI AddVectoredExceptionHandler(   __in  ULONG FirstHandler,   __in  PVECTORED_EXCEPTION_HANDLER VectoredHandler );

IA-32处理器定义了8个调试寄存器(DR0-DR7) DR0-DR3用于指点内存地址或I/O地址 DR4-DR5保留,DR6事件发生报告详细信息,DR7定义中断条件。 硬件断点HOOK是结合DR0-DR3调试寄存器和Winows SEH或VEH机制所引入的HOOK机制,因不涉及修改代码,不易检验检测到。

 

//测试EXE #include #include #include typedef LONG (WINAPI *PVECTOREDEXCEPTIONHANDLER)(PEXCEPTION_POINTERS ExceptionInfo); typedef PVOID (WINAPI *ADDVECTOREEXCEPTIONHANDLER)( ULONG FirstHandler, PVECTOREDEXCEPTIONHANDLER VectoredHandler ); typedef struct _VECTORED_EXCEPTION_NODE { LIST_ENTRY ListEntry; PVECTORED_EXCEPTION_HANDLER pfnHandler; // 该指针出于安全目的已经被加密 } VECTORED_EXCEPTION_NODE, *PVECTORED_EXCEPTION_NODE; LONG CALLBACK VectoredHandlerinit1(struct _EXCEPTION_POINTERS *ExceptionInfo) { return EXCEPTION_CONTINUE_SEARCH; } LONG CALLBACK VectoredHandlerinit2(struct _EXCEPTION_POINTERS *ExceptionInfo) { return EXCEPTION_CONTINUE_SEARCH; } LONG CALLBACK VectoredHandlerinit3(struct _EXCEPTION_POINTERS *ExceptionInfo) { return EXCEPTION_CONTINUE_SEARCH; } LONG CALLBACK VectoredHandler(__in PEXCEPTION_POINTERS ExceptionInfo) { ExceptionInfo; return EXCEPTION_CONTINUE_EXECUTION; } int CheckVEHHook(std::vector& vecVEH, bool bcache, bool bdelete = false) { PVOID pExceptionHandler = NULL; PVECTORED_EXCEPTION_NODE pCurrent = NULL; PVECTORED_EXCEPTION_NODE pNext = NULL, pDel = NULL; pCurrent = (PVECTORED_EXCEPTION_NODE)AddVectoredExceptionHandler(0,VectoredHandler); if( pCurrent == NULL ) { printf("AddVectoredExceptionHandler111 failed.\n"); return 0; } pNext = (PVECTORED_EXCEPTION_NODE)pCurrent->ListEntry.Blink; //pNext = (PVECTORED_EXCEPTION_NODE)pNext->ListEntry.Flink; printf("fake addr:0x%.8x pfnHandler:0x%.8x VEH function.\n", pCurrent, DecodePointer(pCurrent->pfnHandler)); for( ; pNext != pCurrent; ) { pExceptionHandler = DecodePointer(pNext->pfnHandler); if( pExceptionHandler ) { if( bcache ) { vecVEH.push_back(pNext); } printf("found addr:0x%.8x pfnHandler:0x%.8x VEH function.\n",pNext,pExceptionHandler); pNext = (PVECTORED_EXCEPTION_NODE)pNext->ListEntry.Blink; if( bdelete ) { std::vector::iterator findit = find(vecVEH.begin(),vecVEH.end(),pNext); if( findit == vecVEH.end() ) { pDel = pNext; pNext = (PVECTORED_EXCEPTION_NODE)pNext->ListEntry.Blink; printf("#### addr:0x%.8x pfnHandler:0x%.8x VEH function is illegal.\n",pDel,pExceptionHandler); if( RemoveVectoredExceptionHandler(pDel) ) { printf("####the 0x%.8x is deleted.\n",pDel); } else { printf("####delete failed.\n"); } break; } } } } if( RemoveVectoredExceptionHandler(pCurrent) ) { printf("the fake node 0x%.8x is deleted.\n",pCurrent); } else { printf("delete failed.\n"); } return 0; } DWORD func_addr = 0, func_addr_offset = 0; void __declspec(naked) ReturnOriginalFunc(void) { __asm { mov edi,edi //push ebp way 222 jmp [func_addr_offset] } } LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) { if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { func_addr = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"); func_addr_offset = func_addr + 0x2; printf("***catch some exception, don't know who hook that.\n"); if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr) { //if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr+2) { way 222 PCONTEXT debug_context = ExceptionInfo->ContextRecord; printf("only blind cat meet mouse !\n"); debug_context->Eip = (DWORD)&ReturnOriginalFunc; return EXCEPTION_CONTINUE_EXECUTION; } } return EXCEPTION_CONTINUE_SEARCH; } void main() { SetUnhandledExceptionFilter(ExceptionFilter); //事先加3个进去 AddVectoredExceptionHandler(1,VectoredHandlerinit1); AddVectoredExceptionHandler(0,VectoredHandlerinit2); AddVectoredExceptionHandler(1,VectoredHandlerinit3); MessageBox(NULL,"the fact infor111","test SEH hook",MB_OK); std::vector vecVEH; printf("-----------------before LoadLibraryA.----------------\n"); CheckVEHHook(vecVEH,true,false); ::LoadLibraryA("WaiGua.dll"); printf("-----------------after LoadLibraryA.----------------\n"); CheckVEHHook(vecVEH,false,false); MessageBox(NULL,"the fact infor222","test SEH hook",MB_OK); printf("-----------------delete LoadLibraryA added veh.-----\n"); CheckVEHHook(vecVEH,false,true); MessageBox(NULL,"the fact infor333","test SEH hook",MB_OK); //如果用下面的,是字面值需要VirtualProtect,并且和第2个MessageBox指向同一地址,则弹出内容还是被改变的。 //MessageBox(NULL,"the fact infor222","test SEH hook",MB_OK); getchar(); }

 

//VEH hook dll. // VEHHook.cpp : Defines the entry point for the DLL application. // #include #include #include #include #include typedef HANDLE (WINAPI *OPENTHREAD) (DWORD dwFlag, BOOL bUnknow, DWORD dwThreadId); OPENTHREAD g_lpfnOpenThread = NULL; typedef LONG (WINAPI *PVECTOREDEXCEPTIONHANDLER)(PEXCEPTION_POINTERS ExceptionInfo); typedef PVOID (WINAPI *ADDVECTOREEXCEPTIONHANDLER)( ULONG FirstHandler, PVECTOREDEXCEPTIONHANDLER VectoredHandler ); ADDVECTOREEXCEPTIONHANDLER g_AddVectorExceptionHandler = NULL; DWORD func_addr = 0x00401000; DWORD func_addr_offset = func_addr + 0x2; void PrintParameters(PCONTEXT debug_context) { printf("EAX: %X EBX: %X ECX: %X EDX: %X\n", debug_context->Eax, debug_context->Ebx, debug_context->Ecx, debug_context->Edx); printf("ESP: %X EBP: %X\n", debug_context->Esp, debug_context->Ebp); printf("ESI: %X EDI: %X\n", debug_context->Esi, debug_context->Edi); printf("Parameters\n" "HWND: %X\n" "text: %s\n" "caption: %s\n", (HWND)(*(DWORD*)(debug_context->Esp + 0x4)), (char*)(*(DWORD*)(debug_context->Esp + 0x8)), (char*)(*(DWORD*)(debug_context->Esp + 0xC))); } void ChangeText(PCONTEXT debug_context) { char* text = (char*)(*(DWORD*)(debug_context->Esp + 0x8)); int length = strlen(text); DWORD oldprotect = 0; VirtualProtect(text,length,PAGE_EXECUTE_READWRITE,&oldprotect); _snprintf(text, length, "Be Hooked!"); VirtualProtect(text,length,oldprotect,&oldprotect); } void __declspec(naked) ReturnOriginalFunc(void) { __asm { mov edi,edi jmp [func_addr_offset] } } LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) { if(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { if((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == func_addr) { PCONTEXT debug_context = ExceptionInfo->ContextRecord; printf("Breakpoint hit!\n"); PrintParameters(debug_context); ChangeText(debug_context); debug_context->Eip = (DWORD)&ReturnOriginalFunc; return EXCEPTION_CONTINUE_EXECUTION; } } return EXCEPTION_CONTINUE_SEARCH; } void VEHHook(void) { HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if(hTool32 != INVALID_HANDLE_VALUE) { THREADENTRY32 thread_entry32; thread_entry32.dwSize = sizeof(THREADENTRY32); FILETIME exit_time, kernel_time, user_time; FILETIME creation_time; FILETIME prev_creation_time; prev_creation_time.dwLowDateTime = 0xFFFFFFFF; prev_creation_time.dwHighDateTime = INT_MAX; HANDLE hMainThread = NULL; if(Thread32First(hTool32, &thread_entry32)) { do { //取最早启动的线程作为hook对象 if(thread_entry32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(thread_entry32.th32OwnerProcessID) && thread_entry32.th32OwnerProcessID == GetCurrentProcessId() /*&& thread_entry32.th32ThreadID != GetCurrentThreadId()*/) { HANDLE hThread = g_lpfnOpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, thread_entry32.th32ThreadID); GetThreadTimes(hThread, &creation_time, &exit_time, &kernel_time, &user_time); if(CompareFileTime(&creation_time, &prev_creation_time) == -1) { //creation_time 小于 prev_creation_time时候为-1 memcpy(&prev_creation_time, &creation_time, sizeof(FILETIME)); if(hMainThread != NULL) CloseHandle(hMainThread); hMainThread = hThread; } else CloseHandle(hThread); } thread_entry32.dwSize = sizeof(THREADENTRY32); } while(Thread32Next(hTool32, &thread_entry32)); //(void)SetUnhandledExceptionFilter(ExceptionFilter); g_AddVectorExceptionHandler(1, ExceptionFilter); CONTEXT thread_context = {CONTEXT_DEBUG_REGISTERS}; thread_context.Dr0 = func_addr; thread_context.Dr7 = (1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3